package com.test.base.netty.pipeline;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class PipeLineServer {
    /**
     * description 这是一个接受数据的server，用于测试pipeline的响应情况，
     * 主要测试内容是 ChannelHandlerContext和channel调用write的时候，pipeline会从什么位置开始进行写事件pipeline的调用
     * 结论：如果是使用ChannelHandlerContext的话，那就是直接从pipeline的当前位置开始遍历pipeline
     * 如果是使用ChannelHandlerContext所在的channel的话，会重新从tail开始遍历pipeline
     * @author zken
     * @CreateDate 2024/11/20 16:48:39
     */
    public static void main(String[] args) {
        ChannelFuture channelFuture = new ServerBootstrap()
                .group(new NioEventLoopGroup(), new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast("h1", new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                log.debug("h1");
                                super.channelRead(ctx, msg);
                            }
                        });
                        ch.pipeline().addLast("h2", new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                log.debug("h2");
                                super.channelRead(ctx, msg);
                            }
                        });
                        ch.pipeline().addLast("h3", new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                log.debug("h3");
//                                ctx.channel().writeAndFlush("你好");
                                ctx.writeAndFlush("你好");
                                // 区分方法：ctx.writeAndFlush("你好"); 和ctx.channel().writeAndFlush("你好");
                                /*
                                当前的ctx执执行写方法，是从当前位置开始往回遍历pipeline
                                使用ctx的channel进行write，是从pipeline的tail开始进行遍历pipeline
                                 */
//                                super.channelRead(ctx, msg);
                            }
                        });
                        // ChannelOutboundHandlerAdapter写事件的触发，是从后往前的
                        ch.pipeline().addLast("h4", new ChannelOutboundHandlerAdapter() {
                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                log.debug("h4");
                                super.write(ctx, msg, promise);
                            }
                        });
                        ch.pipeline().addLast("h5", new ChannelOutboundHandlerAdapter() {
                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                log.debug("h5");
                                super.write(ctx, msg, promise);

                            }
                        });
                        ch.pipeline().addLast("h6", new ChannelOutboundHandlerAdapter() {
                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                log.debug("h6");
                                super.write(ctx, msg, promise);
                            }
                        });


                    }
                }).bind(8080);
    }

}
